/* AMX Mod X
*   Reconnect Delay
*
* (c) Copyright 2005 by VEN aka VnMnL
*
* This file is provided as is (no warranties)
*/

/* ************************************************** Defines ************************************************** */

// Uncomment for AMX Mod compatibility
//#define AMX_COMPATIBLE

// Uncomment to log to separate file
//#define LOG_SEPARATE "reconnectdelay.log"

// Uncomment to log details
//#define LOG_DETAIL

// Max. IP entries
#define IP_ENTRIES 32

// Max. reconnect delay in seconds
#define MAX_DELAY 300

// Comment to not obey immunity
#define OBEY_IMMUNITY

// Immunity access level
#define ACCESS_IMMUNITY ADMIN_IMMUNITY

/* *************************************************** Init **************************************************** */

#if !defined AMX_COMPATIBLE
	#include <amxmodx>
#else
	#include <amxmod>
#endif

new g_ip_list[IP_ENTRIES][24]
new Float:g_leave_time[IP_ENTRIES]
new g_enter_count[IP_ENTRIES]

public plugin_init() {
	register_plugin("Reconnect Delay", "0.4", "VEN aka VnMnL")

	register_cvar("amx_reconnect_delay", "25")
	register_cvar("amx_reconnect_maxtimes", "0")
	register_cvar("amx_reconnect_bantime", "30.0")
}

/* *************************************************** Base **************************************************** */

public client_authorized(id) {
	enter_leave(id, false)
}

public client_disconnect(id) {
	enter_leave(id, true)
}

enter_leave(id, bool:leave) {
	if (is_user_bot(id))
		return

#if defined OBEY_IMMUNITY
	if (get_user_flags(id) & ACCESS_IMMUNITY)
		return
#endif

	new Float:delay = get_cvar_float("amx_reconnect_delay")
	if (delay <= 0)
		return

	if (delay > MAX_DELAY)
		delay = float(MAX_DELAY)

	new ip[24]
	get_user_ip(id, ip, 23, 0)
	new Float:gametime = get_gametime()

	if (leave) {
		for (new i = 0; i < IP_ENTRIES; ++i) {
			if (equal(ip, g_ip_list[i]) && gametime < g_leave_time[i] + delay)
				return
		}

		for (new i = 0; i < IP_ENTRIES; ++i) {
			if (!g_ip_list[i][0] || gametime >= g_leave_time[i] + delay) {
				g_ip_list[i] = ip
				g_leave_time[i] = gametime
				return
			}
		}

		log_msg("Reconnect Delay Warning: All IP entries are full, you may increase defined value in plugin source")
		return
	}

	for (new i = 0; i < IP_ENTRIES; ++i) {
		if (!equal(ip, g_ip_list[i]))
			continue

		if (gametime >= g_leave_time[i] + delay) {
			g_enter_count[i] = 0
			return
		}

		g_enter_count[i]++
		new pentype[7]
		new userid = get_user_userid(id)
		new maxtimes = get_cvar_num("amx_reconnect_maxtimes")
		if (g_enter_count[i] == maxtimes) {
			g_enter_count[i] = 0
			pentype = "banned"
			new banip[16]
			get_user_ip(id, banip, 15, 1)
			new Float:bantime = get_cvar_float("amx_reconnect_bantime")
			server_cmd("kick #%d ^"You has been banned for %.1f min for using reconnect %d time%s^"", userid, bantime, maxtimes, maxtimes > 1 ? "s" : "")
			server_cmd("addip ^"%f^" ^"%s^"", bantime, banip)
		}
		else {
			pentype = "kicked"
			new Float:left = g_leave_time[i] + delay - gametime
			if (left < 0.5)
				left = 1.0
			server_cmd("kick #%d ^"You can not connect at this time, please try again after %.0f second%s^"", userid, left, left < 1.5 ? "" : "s")
		}

#if defined LOG_DETAIL
		new name[32], message[128]
		get_user_name(id, name, 31)
		format(message, 127, "Reconnect Delay: Client ^"%s<%d><%s>^" %s", name, userid, ip, pentype)
		log_msg(message)
#endif

		return
	}
}

/* ************************************************** Stocks *************************************************** */

stock log_msg(message[]) {
#if !defined LOG_SEPARATE
  #if !defined AMX_COMPATIBLE
	log_amx(message)
  #else
	new log_file[16]
	get_time("admin%m%d.log", log_file, 15)
	log_to_file(log_file, message)
  #endif
#else
	log_to_file(LOG_SEPARATE, message)
#endif
}

/* **************************************************** EOF **************************************************** */
